package fag.core.game.test.pong;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;

import fag.core.collision.Collision;
import fag.core.game.AbstractGame;
import fag.core.game.Transformable.Referential;
import fag.core.game.test.pong.Ball;
import fag.core.geometry.Vector2D;

//Touche C,V et <-,->

public class Pong extends AbstractGame implements KeyListener {
	
	public static void main(String[] args) {
		Pong pong = new Pong();
		pong.run();
	}
	
	public static final int WIDTH = 600;
	public static final int HEIGHT = 400;
	private JFrame frame;
	private PongCamera camera = new PongCamera();	
	private PongScene scene = new PongScene();
	private Racket[] racket = new Racket[2];
	private Ball ball;
	
	Pong() {
		camera.setSize(WIDTH, HEIGHT);
		scene.addCamera(camera);
		scene.addDoodad(racket[0] = new Racket(new RacketModel("racket_bleu")));
		scene.addDoodad(racket[1] = new Racket(new RacketModel("racket_rouge")));
		addScene(scene);
		startPong();
		
		frame = new JFrame("Pong");
		frame.setSize(WIDTH, HEIGHT);
		frame.setResizable(false);
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(camera);
		frame.pack();
		frame.addKeyListener(this);
	}
	
	private void startPong() {
		racket[0].setTranslation(5, HEIGHT / 2 - racket[0].getBounds().getHeight() / 2);
		racket[1].setTranslation(WIDTH - racket[1].getBounds().getWidth() - 5, HEIGHT / 2 - racket[1].getBounds().getHeight() / 2);
		initBall();
	}
	
	private void initBall() {
		if(ball != null) {
			scene.removeDoodad(ball);
		}
		double random;
		do {
			random = Math.random();
		} while(
			(random >= 0.0 / 12.0 && random < 1.0 / 12.0) ||
			(random >= 2.0 / 12.0 && random < 4.0 / 12.0) ||
			(random >= 5.0 / 12.0 && random < 7.0 / 12.0) ||
			(random >= 8.0 / 12.0 && random < 10.0 / 12.0) ||
			(random >= 11.0 / 12.0 && random < 12.0 / 12.0)
		);
		scene.addDoodad(ball = new Ball(new BallModel("balle"), new Vector2D(Math.cos(random * Math.PI * 2) * 150, Math.sin(random * Math.PI * 2) * 150)));
		ball.setTranslation(WIDTH / 2 - ball.getBounds().getWidth() / 2, HEIGHT / 2 - ball.getBounds().getHeight() / 2);
	}

	@Override
	public void step(double dt) {
		for(int i = 0; i < racket.length; i++) {
			Collision collision = racket[i].getHitbox().getCollision(ball.getHitbox());			
			if(collision.isColliding()) {
				Vector2D normal = collision.getNormal();
				Vector2D separator = normal.mul(collision.getPenetration() * 1).add(normal);
				ball.translate(separator, Referential.ABSOLUTE);
				ball.bounce(normal.mul(-1));
			}
		}
		if(ball.getTranslationX() - ball.getBounds().getWidth() / 2 < 0) {
			initBall();
			scene.score2++;
			camera.repaint();
		}
		else if(ball.getTranslationX() - ball.getBounds().getWidth() / 2 > WIDTH) {
			initBall();
			scene.score1++;
			camera.repaint();
		}
		if(ball.getTranslationY() - ball.getBounds().getHeight() / 2 < 0) {
			ball.bounce(new Vector2D(0, 1));
		}
		else if(ball.getTranslationY() + ball.getBounds().getHeight() / 2 > HEIGHT) {
			ball.bounce(new Vector2D(0, -1));
		}
		ball.step(dt / 1000);
	}

	@Override
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode() == KeyEvent.VK_C) {
			if(racket[0].getBounds().getY() - 10 < 0) {
				racket[0].setTranslation(racket[0].getBounds().getX(), 0);
			} else {
				racket[0].setTranslation(racket[0].getBounds().getX(), racket[0].getBounds().getY() - 10);
			}
		} else if(e.getKeyCode() == KeyEvent.VK_V) {
			if(racket[0].getBounds().getY() + racket[0].getBounds().getHeight() + 10 > HEIGHT) {
				racket[0].setTranslation(racket[0].getBounds().getX(), HEIGHT - racket[0].getBounds().getHeight());
			} else {
				racket[0].setTranslation(racket[0].getBounds().getX(), racket[0].getBounds().getY() + 10);
			}
		} else if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
			if(racket[1].getBounds().getY() - 10 < 0) {
				racket[1].setTranslation(racket[1].getBounds().getX(), 0);
			} else {
				racket[1].setTranslation(racket[1].getBounds().getX(), racket[1].getBounds().getY() - 10);
			}
		} else if(e.getKeyCode() == KeyEvent.VK_LEFT) {
			if(racket[1].getBounds().getY() + racket[1].getBounds().getHeight() + 10 > HEIGHT) {
				racket[1].setTranslation(racket[1].getBounds().getX(), HEIGHT - racket[1].getBounds().getHeight());
			} else {
				racket[1].setTranslation(racket[1].getBounds().getX(), racket[1].getBounds().getY() + 10);
			}
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {}

	@Override
	public void keyTyped(KeyEvent e) {}

}
